package mao.concurent.parallel;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * @author Totoro
 * @date 2020/7/10
 * @explain:  并行计算的。
 */


public class Parallel {
    public static void main(String[] args) {
        int N=80000000;
        Integer[] arr= new Integer[N];
        for(int i = 0;i<N;i++){
            arr[i] = (int) (N*Math.random());
        }

        long start = System.currentTimeMillis();
        System.out.println(Max(arr));
        long end = System.currentTimeMillis();
        System.out.println("并行计算");
        System.out.println((int)Runtime.getRuntime().availableProcessors()+"  " + (end-start));

        start = System.currentTimeMillis();
        int max = arr[0];

        for(int i=0;i<arr.length;i++){
            if(arr[i] > max){
                max = arr[i];
            }
        }
        end = System.currentTimeMillis();
        System.out.println(max);
        System.out.println("串性计算");
        System.out.println((int)Runtime.getRuntime().availableProcessors()+"  " + (end-start));



    }

    public static Integer Max(Integer[] arr){
        RecursiveTask<Integer> parallelMax = new ParallelMax(arr,0,arr.length);
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        Integer invoke = forkJoinPool.invoke(parallelMax);
        return invoke;

    }


    public static class ParallelMax extends RecursiveTask<Integer>{
        /**
         *
         */
        private static final long serialVersionUID = 1L;
        Integer[] arr;
        int start = 0;
        int end = 0;
        private final int THRESHOLD = 1000000;



        public ParallelMax(Integer[] arr, int start, int end) {
            super();
            this.arr = arr;
            this.start = start;
            this.end = end;
        }



        @Override
        protected Integer compute() {
            int max = arr[start];
            if(end - start < THRESHOLD){
                for(int i=start;i<end;i++){
                    if(arr[i] > max){
                        max = arr[i];
                    }
                }
                return max;
            }else{

                //此处需要注意(end+start)/2;
                RecursiveTask<Integer> parallelMax1 = new ParallelMax(arr,start, (end+start)/2);
                RecursiveTask<Integer> parallelMax2 = new ParallelMax(arr, (end+start)/2,end);

                Integer result1 = parallelMax1.invoke();
                 Integer result2 = parallelMax2.invoke();

			parallelMax1.fork();
			parallelMax2.fork();

			Integer join1 = parallelMax1.join();
			Integer join2 = parallelMax2.join();
                return Math.max(join1, join2);
            }

        }

    }
}
